import React, { FunctionComponent } from 'react';
import useHelper from 'src/utils/hooks/useHelper';
import { graphql } from 'react-relay';
import { MalwareAnalysesLinesPaginationQuery, MalwareAnalysesLinesPaginationQuery$variables } from '@components/analyses/__generated__/MalwareAnalysesLinesPaginationQuery.graphql';
import { MalwareAnalysesLines_data$data } from '@components/analyses/__generated__/MalwareAnalysesLines_data.graphql';
import { usePaginationLocalStorage } from '../../../utils/hooks/useLocalStorage';
import Security from '../../../utils/Security';
import { KNOWLEDGE_KNUPDATE } from '../../../utils/hooks/useGranted';
import MalwareAnalysisCreation from './malware_analyses/MalwareAnalysisCreation';
import useQueryLoading from '../../../utils/hooks/useQueryLoading';
import { emptyFilterGroup, useBuildEntityTypeBasedFilterContext } from '../../../utils/filters/filtersUtils';
import { useFormatter } from '../../../components/i18n';
import ExportContextProvider from '../../../utils/ExportContextProvider';
import Breadcrumbs from '../../../components/Breadcrumbs';
import DataTable from '../../../components/dataGrid/DataTable';
import { DataTableProps } from '../../../components/dataGrid/dataTableTypes';
import { UsePreloadedPaginationFragment } from '../../../utils/hooks/usePreloadedPaginationFragment';
import useConnectedDocumentModifier from '../../../utils/hooks/useConnectedDocumentModifier';

const LOCAL_STORAGE_KEY = 'malwareAnalyses';

const malwareAnalysisFragment = graphql`
  fragment MalwareAnalysesLine_node on MalwareAnalysis {
    id
    standard_id
    product
    entity_type
    operatingSystem {
      name
    }
    submitted
    result_name
    createdBy {
      ... on Identity {
        id
        name
        entity_type
      }
    }
    creators {
      id
      name
    }
    modified
    objectMarking {
      id
      definition_type
      definition
      x_opencti_order
      x_opencti_color
    }
    objectLabel {
      id
      value
      color
    }
  }
`;

const malwareAnalysesLinesQuery = graphql`
  query MalwareAnalysesLinesPaginationQuery(
    $search: String
    $count: Int
    $cursor: ID
    $orderBy: MalwareAnalysesOrdering
    $orderMode: OrderingMode
    $filters: FilterGroup
  ) {
    ...MalwareAnalysesLines_data
    @arguments(
      search: $search
      count: $count
      cursor: $cursor
      orderBy: $orderBy
      orderMode: $orderMode
      filters: $filters
    )
  }
`;

const malwareAnalysesLinesFragment = graphql`
  fragment MalwareAnalysesLines_data on Query
  @argumentDefinitions(
    search: { type: "String" }
    count: { type: "Int" }
    cursor: { type: "ID" }
    orderBy: { type: "MalwareAnalysesOrdering" }
    orderMode: { type: "OrderingMode" }
    filters: { type: "FilterGroup" }
  ) @refetchable(queryName: "MalwareAnalysesLinesRefetchQuery") {
    malwareAnalyses(
      search: $search
      first: $count
      after: $cursor
      orderBy: $orderBy
      orderMode: $orderMode
      filters: $filters
    ) @connection(key: "Pagination_malwareAnalyses") {
      edges {
        node {
          id
          product
          submitted
          ...MalwareAnalysesLine_node
        }
      }
      pageInfo {
        endCursor
        hasNextPage
        globalCount
      }
    }
  }
`;

const MalwareAnalyses: FunctionComponent = () => {
  const { t_i18n } = useFormatter();
  const { setTitle } = useConnectedDocumentModifier();
  setTitle(t_i18n('Malware Analyses | Analyses'));
  const { isFeatureEnable } = useHelper();
  const isFABReplaced = isFeatureEnable('FAB_REPLACEMENT');
  const initialValues = {
    searchTerm: '',
    sortBy: 'submitted',
    orderAsc: false,
    openExports: false,
    filters: emptyFilterGroup,
  };
  const { viewStorage, helpers: storageHelpers, paginationOptions } = usePaginationLocalStorage<MalwareAnalysesLinesPaginationQuery$variables>(
    LOCAL_STORAGE_KEY,
    initialValues,
  );
  const {
    filters,
  } = viewStorage;

  const contextFilters = useBuildEntityTypeBasedFilterContext('Malware-Analysis', filters);
  const queryPaginationOptions = {
    ...paginationOptions,
    filters: contextFilters,
  } as unknown as MalwareAnalysesLinesPaginationQuery$variables;
  const queryRef = useQueryLoading<MalwareAnalysesLinesPaginationQuery>(
    malwareAnalysesLinesQuery,
    queryPaginationOptions,
  );

  const preloadedPaginationProps = {
    linesQuery: malwareAnalysesLinesQuery,
    linesFragment: malwareAnalysesLinesFragment,
    queryRef,
    nodePath: ['malwareAnalyses', 'pageInfo', 'globalCount'],
    setNumberOfElements: storageHelpers.handleSetNumberOfElements,
  } as UsePreloadedPaginationFragment<MalwareAnalysesLinesPaginationQuery>;

  const dataColumns: DataTableProps['dataColumns'] = {
    result_name: {},
    product: {},
    operatingSystem: {},
    createdBy: { percentWidth: 10 },
    creator: { percentWidth: 10 },
    objectLabel: {},
    submitted: {},
    objectMarking: {},
  };

  return (
    <ExportContextProvider>
      <Breadcrumbs variant="list" elements={[{ label: t_i18n('Analyses') }, { label: t_i18n('Malware analyses'), current: true }]} />
      {queryRef && (
        <DataTable
          dataColumns={dataColumns}
          resolvePath={(data: MalwareAnalysesLines_data$data) => data.malwareAnalyses?.edges?.map((n) => n?.node)}
          storageKey={LOCAL_STORAGE_KEY}
          initialValues={initialValues}
          toolbarFilters={contextFilters}
          preloadedPaginationProps={preloadedPaginationProps}
          lineFragment={malwareAnalysisFragment}
          exportContext={{ entity_type: 'Malware-Analysis' }}
          createButton={isFABReplaced && (
            <Security needs={[KNOWLEDGE_KNUPDATE]}>
              <MalwareAnalysisCreation paginationOptions={queryPaginationOptions} />
            </Security>
          )}
        />
      )}
      {!isFABReplaced && (
        <Security needs={[KNOWLEDGE_KNUPDATE]}>
          <MalwareAnalysisCreation paginationOptions={queryPaginationOptions} />
        </Security>
      )}
    </ExportContextProvider>
  );
};

export default MalwareAnalyses;
